package cn.lesaas.nof.core.c.communications.ncbs.callers;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import bea.jolt.JoltRemoteService;
import bea.jolt.JoltSession;
import bea.jolt.JoltSessionAttributes;
import bea.jolt.ServiceException;

//1.3、国际化
//
//由于Jolt客户端与Tuxedo交互时，相互传递的参数可能包含中文，因此，要对传输的内容进行国际化。步骤如下：

//Tuxedo服务器端

//在主机上添加下面的环境变量，重启Tuxedo服务器，JSH会参照此变量。
//
//JOLTI18N=TRUE  .但是jolt的repository编辑器将不好使
//
//Jolt客户端
//
//将jolti18n.jar添加到classpath下，并在系统参数中添加如下属性，其中，charsetName代表Jolt客户端与tuxedo交互时使用的字符编码集，该字符编码集必须在客户端和服务器上都支持，如GBK。
//
//bea.jolt.encoding=charsetName
//
//系统属性的添加方法有如下两种：
//
//$java ... -Dbea.jolt.encoding=codesetname ...
//
//或 System.setProperty("bea.jolt.encoding", joltEncoding);
//
//１、修改tuxedo主机环境变量：
//export JOLTI18N=true
//２、weblogic的启到参数加上：
//-Dbea.jolt.encoding=GBK
//
//但是在使用bea.jolt.admin.jbld 时，可能需要把JOLTI18N=TRUE去掉

public class NcbsJoltTuxedoCaller {
    
    private static final Logger logger = LoggerFactory.getLogger(NcbsJoltTuxedoCaller.class);
    
    public static final String TUXEDO_ROLE = "core.ncbs.tuxedo.role";
    public static final String TUXEDO_BLKSIZE = "core.ncbs.tuxedo.blksize";
    public static final String TUXEDO_USERNAME = "core.ncbs.tuxedo.username";
    public static final String TUXEDO_PASSWORD = "core.ncbs.tuxedo.password";
    public static final String TUXEDO_APPPASSWORD = "core.ncbs.tuxedo.apppassword";
    public static final String TUXEDO_CHARSET = "core.ncbs.tuxedo.charset";/* 编码类型 */


	//private static int TIMEOUTSECOND = Integer.valueOf(CommunicationCfgUtil.getTUXDO_Property(CommunicationCfgUtil.TUXEDO_TIMEOUTSECOND));
	private static int BLKSIZE = 1024;
	// private static int EXTENSIZE=200;
	private static String userRole = "admin";
	private static String userName = "";
	private static String userPassword = "";
	private static String appPassword = "";
	private static String tuxedoCharsetName = "utf-8";
	private static Charset tuxedoCharset = Charset.forName(tuxedoCharsetName);// Charset.forName("iso8859-1");////

	private static final ConcurrentHashMap<String, JoltSession> sessions = new ConcurrentHashMap<String, JoltSession>();
	private static final ConcurrentHashMap<String, JoltRemoteService> services = new ConcurrentHashMap<String, JoltRemoteService>();

	public String doCall(String jydm, String req)
			throws Exception {

		JoltRemoteService jrs = getService("test", jydm);

		if (jrs == null) {
			throw new Exception("jrs=null");
		}

		jrs.setString("STRING", req);

		String recvStr;

		try {
			jrs.call(null);
			recvStr = jrs.getStringDef("STRING", null);
		} catch (ServiceException e) {
			throw new Exception(e.getMessage());
		}
        finally {
            jrs.clear();
            jrs.done();
            jrs = null;
        }

		if (recvStr == null) {
			throw new Exception("recvStr==null");
		}

		return recvStr;
	}

	/*public void doCallCarray(String jydm, PackStruct req, PackStruct res)
			throws Exception {

		JoltRemoteService jrs = getService(getZjxx().getZjdm(), jydm);
		 考虑到多线程的所以jrs可以
		if (services.containsKey(jydm)) {
			jrs = services.get(jydm);
		} else {
			jrs = getService(getZjxx().getZjdm(), jydm);
			services.put(jydm, jrs);
		}
		

		if (jrs == null) {
			throw new Exception(InternationalUtil.getMessage
					(InternationlConstants.TUXEDO));
		}

		int nBufferSize = 8 + req.header.length + req.body.length;
		byte[] sendBuffer = new byte[nBufferSize];

		int offset = 8;

		PackBase.formatInt(nBufferSize, sendBuffer, 0, offset);

		try {
			System.arraycopy(req.header, 0, sendBuffer, offset,
					req.header.length);
			offset += req.header.length;

			System.arraycopy(req.body, 0, sendBuffer, offset, req.body.length);

			jrs.setBytes("CARRAY", sendBuffer, sendBuffer.length);

			try {
				jrs.call(null);
			} catch (ServiceException e) {
				// jrs = reconnect();
				// jrs.setBytes("CARRAY", sendBuffer, sendBuffer.length);
				// jrs.call(null);
				throw new Exception(e.getMessage());
			}

			byte[] recvBuffer = jrs.getBytesDef("CARRAY", null);
			if (recvBuffer == null) {
				throw new Exception(InternationalUtil.getMessage
						(InternationlConstants.PACKETS_IS_EMPTY));
			}
		}
		finally {
		    jrs.clear();
		    jrs.done();
		    jrs = null;
		}
	}*/
	
	//TODO YBY-T synchronized 利用同步HashMap就不用管这个
	 public JoltRemoteService getService(String zjdm, String name) {
		JoltRemoteService jrs = null;

		JoltSession session = sessions.get(zjdm);

		if (session == null || !session.isAlive()) {
			if (session != null)
				sessions.remove(zjdm);

			//System.setProperty("bea.jolt.encoding", tuxedoCharsetName); // 必须和后台JOLTI18N配合使用

/*			Zjxx zjxx = getZjxx();
			zjxx.getIpad()
			zjxx.getPort()*/
			String ip = "127.0.0.1";
			String port = "8811";
			int cssj = 30;
				
			String sessionAttributesString = "//" + ip + ":"
					+ port;
			
			logger.debug("jolt open session:[{}]",sessionAttributesString);


			JoltSessionAttributes sattr = new JoltSessionAttributes();
			sattr.setString(JoltSessionAttributes.APPADDRESS,
					sessionAttributesString);
			switch (sattr.checkAuthenticationLevel()) {
			case JoltSessionAttributes.NOAUTH:
				break;
			case JoltSessionAttributes.APPASSWORD:
				// appPassword = zjxx.gett();
				break;
			case JoltSessionAttributes.USRPASSWORD:
				// userName = zjxx.getUserName();
				// userPassword = zjxx.getUserPassword();
				// appPassword = zjxx.getAppPassword();
				break;
            default:
                break;
			}

			if (appPassword == null)
				appPassword = "";
			if (userName == null)
				userName = "";
			if (userPassword == null)
				userPassword = "";

			sattr.setInt(JoltSessionAttributes.IDLETIMEOUT, 0);
			sattr.setInt(JoltSessionAttributes.RECVTIMEOUT, cssj);
			sattr.setInt(JoltSessionAttributes.SENDTIMEOUT, cssj);

			session = new JoltSession(sattr, userName, userRole, userPassword,
					appPassword);

			sessions.put(zjdm, session);
		}
		try
		{
		    jrs = new JoltRemoteService(name, session);
		}
		catch(Exception e)
		{
		    sessions.remove(zjdm);
		    throw e;
		}

		return jrs;
	}

	public JoltRemoteService reconnect() {
		JoltRemoteService jrs = null;
		// if (session != null) {
		// JoltSessionAttributes sattr = new JoltSessionAttributes();
		// sattr.setString(JoltSessionAttributes.APPADDRESS,
		// session.sessionAttributesString);
		// sattr.setInt(JoltSessionAttributes.IDLETIMEOUT, 0);
		// sattr.setInt(JoltSessionAttributes.RECVTIMEOUT, TIMEOUTSECOND);
		// sattr.setInt(JoltSessionAttributes.SENDTIMEOUT, TIMEOUTSECOND);
		// TUXEDOSession newSession = new TUXEDOSession(sattr, session);
		// session = newSession;
		// jrs = new JoltRemoteService(name, session);
		// }
		return jrs;
	}

	/*public void putFile(File file, String name) throws IOException {
		JoltRemoteService jrs = null;
		FileInputStream fis;
		int ftpblocksize, ftpfilesize, ftpleftsize;
		int i;

		ftpfilesize = (int) file.length();
		fis = new FileInputStream(file);

		byte buf[] = new byte[BLKSIZE];

		try {

			jrs = getService(getZjxx().getZjdm(), "ftpsrv");

			jrs.addString("FTPFLAG", "1");
			jrs.addString("FTPFILENAME", name);

			i = 1;
			ftpleftsize = ftpfilesize;

			while (ftpleftsize >= 0) {
				if (ftpleftsize >= BLKSIZE)
					ftpblocksize = BLKSIZE;
				else
					ftpblocksize = ftpleftsize;

				if (ftpblocksize > 0) {
					fis.read(buf, 0, ftpblocksize);
					jrs.setBytes("FTPFILEDATA", buf, ftpblocksize);

				}

				ftpblocksize = BLKSIZE;
				jrs.setInt("FTPBLOCKID", i);
				jrs.setInt("FTPBLOCKSIZE", ftpblocksize);
				jrs.setInt("FTPFILESIZE", ftpfilesize);
				jrs.setBytes("FTPFILEDATA", buf, ftpblocksize);

				jrs.call(null);

				ftpleftsize -= ftpblocksize;
				i++;
			}

		} finally {
			fis.close();
		}

	}*/

	/*public void getFile(File file, String name) throws IOException {
		JoltRemoteService jrs = null;

		FileOutputStream fos;
		fos = new FileOutputStream(file.getPath());

		byte buf[] = new byte[BLKSIZE];

		try {

			jrs = getService(getZjxx().getZjdm(), "ftpsrv");

			int ftpblocksize, ftpfilesize, ftpreadsize;
			int i;
			jrs.addString("FTPFLAG", "2");
			jrs.addString("FTPFILENAME", name);

			// jrs.addString("FTPBLOCKSIZE", BLKSIZE);
			// jrs.addInt("FTPBLOCKID", 0);

			i = 1;
			ftpreadsize = 0;
			do {
				ftpblocksize = BLKSIZE;
				jrs.setInt("FTPBLOCKID", i);
				jrs.setInt("FTPBLOCKSIZE", BLKSIZE);

				jrs.call(null);

				ftpfilesize = jrs.getIntDef("FTPFILESIZE", -1);
				ftpblocksize = jrs.getIntDef("FTPBLOCKSIZE", -1);

				if (ftpblocksize > 0) {
					buf = jrs.getBytesDef("FTPFILEDATA", buf);
					fos.write(buf, 0, ftpblocksize);
				}

				ftpreadsize += ftpblocksize;
				i++;

			} while (ftpreadsize < ftpfilesize);
			fos.flush();
		} finally {
			fos.close();
		}
	}*/

	public static void clearSessionsMap()
	{
	    services.clear();
	    sessions.clear();
	}

	public static void clearServicesMap()
	{
	    services.clear();
	}

	/**
	 * 在服务器端，必须要设置 FLDTBLDIR32和FIELDTBLS32 # mkfldhdr mkfldhdr32 #export
	 * FLDTBLDIR=$HOME/etc #export FIELDTBLS=ftp.tbl export
	 * FLDTBLDIR32=$HOME/etc export FIELDTBLS32=ftp.tbl
	 * @throws Exception 
	 *
	 *
	 **/
	
	public static void main(String[] args) throws Exception {
		NcbsJoltTuxedoCaller caller = new NcbsJoltTuxedoCaller();
		System.out.println(caller.doCall("TOUPPER", "nihao"));
	}
}
